using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;

namespace MyPhotoIndex.Controls
{
    public class ZoomTrackBar : UserControl
    {
        public event EventHandler MinusButonClick;
        public event EventHandler PlusButonClick;
        public event EventHandler ValueChanged;

        private Image ms_minus = Resources.Resources.zoomTrackBar_Minus;
        private Image ms_minus_hl = Resources.Resources.zoomTrackBar_Minus_hl;
        private Image ms_plus = Resources.Resources.ZoomTrackBar_Plus;
        private Image ms_plus_hl = Resources.Resources.ZoomTrackBar_Plus_hl;

        private Image ms_thumb = Resources.Resources.zoomTrackBar_Thumb;
        private Image ms_thumb_hl = Resources.Resources.zoomTrackBar_Thumb_hl;

        private Rectangle m_sliderRect;
        private Rectangle m_minusRect;
        private Rectangle m_plusRect;

        private bool m_onMinus;
        private bool m_onPlus;
        private bool m_onSlider;

        private int m_maximum;
        private int m_minimum;
        private int m_value;

        private bool m_sliderMouseDown;
        private int m_sliderMousePosition;
        private Padding m_sliderBorders;

        private String m_minusToolTip;
        private String m_plusToolTip;
        private ToolTip m_tooltip = new ToolTip();

        private bool m_transparent = false;

        public ZoomTrackBar()
        {
            int x = (this.ClientRectangle.Width - ms_thumb.Width) / 2;
            m_sliderRect = new Rectangle(x, 2, ms_thumb.Width, ms_thumb.Height);
            m_maximum = 10;

            InitializeComponent();

            this.MouseMove += new MouseEventHandler(ZoomTrackBar_MouseMove);
            this.MouseLeave += new EventHandler(ZoomTrackBar_MouseLeave);
            this.MouseDown += new MouseEventHandler(ZoomTrackBar_MouseDown);
            this.MouseUp += new MouseEventHandler(ZoomTrackBar_MouseUp);
            this.MouseClick += new MouseEventHandler(ZoomTrackBar_MouseClick);

            Calculate();
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // ZoomTrackBar
            // 
            this.Name = "ZoomTrackBar";
            this.Size = new System.Drawing.Size(339, 150);
            this.ResumeLayout(false);
        }

        [Browsable(true)]
        public bool Transparent
        {
            get { return m_transparent; }
            set { m_transparent = value; }
        }

        [Browsable(true)]
        [Localizable(true)]
        public String MinusToolTip
        {
            get { return m_minusToolTip; }
            set { m_minusToolTip = value; }
        }

        [Browsable(true)]
        [Localizable(true)]
        public String PlusToolTip
        {
            get { return m_plusToolTip; }
            set { m_plusToolTip = value; }
        }

        public int Maximum
        {
            get { return m_maximum; }
            set { m_maximum = value; }
        }

        public int Minimum
        {
            get { return m_minimum; }
            set { m_minimum = value; }
        }

        public int Value
        {
            get { return m_value; }
            set
            {
                if (m_minimum < m_maximum)
                {
                    if (value < m_minimum ||
                        value > m_maximum ||
                        value == m_value)
                    {
                        return;
                    }
                }
                else
                {
                    if (value > m_minimum ||
                        value < m_maximum ||
                        value == m_value)
                    {
                        return;
                    }
                }

                m_value = value;
                int oneStop = (m_sliderBorders.Right - m_sliderBorders.Left) / (m_maximum - m_minimum);
                m_sliderRect.X = (m_value - m_minimum) * oneStop;
                m_sliderRect.X += m_sliderBorders.Left;
                if (m_sliderRect.X < m_sliderBorders.Left)
                {
                    m_sliderRect.X = m_sliderBorders.Left;
                }
                else
                if (m_sliderRect.X > m_sliderBorders.Right)
                {
                    m_sliderRect.X = m_sliderBorders.Right;
                }
                else
                if (m_value == m_maximum)
                {
                    m_sliderRect.X = m_sliderBorders.Right;
                }
                else
                if (m_value == m_minimum)
                {
                    m_sliderRect.X = m_sliderBorders.Left;
                }

                this.Invalidate();

                if (ValueChanged != null)
                {
                    ValueChanged.Invoke(this, EventArgs.Empty);
                }
            }
        }

        void ZoomTrackBar_MouseClick(object sender, MouseEventArgs e)
        {
            Rectangle thumbAreaRect = new Rectangle(m_sliderBorders.Left, m_sliderBorders.Top, m_sliderBorders.Right - m_sliderBorders.Left, m_sliderBorders.Bottom - m_sliderBorders.Top);

            if (m_minusRect.Contains(e.Location) == true)
            {
                Value = (m_minimum < m_maximum) ? m_value - 1 : m_value + 1;
                if (MinusButonClick != null)
                {
                    MinusButonClick.Invoke(this, EventArgs.Empty);
                }
            }
            else
            if (m_plusRect.Contains(e.Location) == true)
            {
                Value = (m_minimum < m_maximum) ? m_value = 1 : m_value - 1;
                if (PlusButonClick != null)
                {
                    PlusButonClick.Invoke(this, EventArgs.Empty);
                }
            }
            else
            if (thumbAreaRect.Contains(e.Location) == true)
            {
                m_sliderMouseDown = true;
                this.ZoomTrackBar_MouseMove(this, new MouseEventArgs(MouseButtons.Left, 1, e.X, e.Y, 0));
                m_sliderMouseDown = false;
            }
        }

        void ZoomTrackBar_MouseUp(object sender, MouseEventArgs e)
        {
            m_sliderMouseDown = false;
        }

        void ZoomTrackBar_MouseDown(object sender, MouseEventArgs e)
        {
            if (m_sliderRect.Contains(e.Location) == true)
            {
                m_sliderMouseDown = true;
                m_sliderMousePosition = e.Location.X;
            }
        }

        void ZoomTrackBar_MouseLeave(object sender, EventArgs e)
        {
            ClearHighLights();
            m_sliderMouseDown = false;
        }

        void ZoomTrackBar_MouseMove(object sender, MouseEventArgs e)
        {
            if (m_sliderMouseDown == false)
            {
                if (m_minusRect.Contains(e.Location) == true)
                {
                    if (m_onMinus == false)
                    {
                        m_onMinus = true;
                        m_onPlus = false;
                        m_onSlider = false;

                        m_tooltip.SetToolTip(this, m_minusToolTip);
                        Invalidate();
                    }
                }
                else
                    if (m_plusRect.Contains(e.Location) == true)
                    {
                        if (m_onPlus == false)
                        {
                            m_onMinus = false;
                            m_onPlus = true;
                            m_onSlider = false;

                            m_tooltip.SetToolTip(this, m_plusToolTip);                       
                            Invalidate();
                        }
                    }
                    else
                    if (m_sliderRect.Contains(e.Location) == true)
                    {
                        if (m_onSlider == false)
                        {
                            m_onMinus = false;
                            m_onPlus = false;
                            m_onSlider = true;

                           m_tooltip.SetToolTip(this, String.Empty);
                           Invalidate();
                        }
                    }
                    else
                    {
                        if (m_onSlider == true ||
                            m_onMinus == true ||
                            m_onPlus == true)
                        {
                            m_onMinus = false;
                            m_onPlus = false;
                            m_onSlider = false;

                            m_tooltip.SetToolTip(this, String.Empty);    
                            Invalidate();
                        }
                    }
            }
            else
            {
                m_onMinus = false;
                m_onPlus = false;
                m_tooltip.SetToolTip(this, String.Empty);

                int newValue = e.X - 5;
                if (m_sliderRect.X != newValue &&
                    m_sliderBorders.Left < newValue &&
                    m_sliderBorders.Right > newValue)
                {
                    m_sliderRect.X = e.X - 5;
                    m_sliderMousePosition = m_sliderRect.X;
                    Invalidate();

                    int oneStop = (m_sliderBorders.Right - m_sliderBorders.Left) / (m_maximum - m_minimum);
                    int oldValue = m_value;
                    m_value = ((m_sliderRect.X - m_sliderBorders.Left) / oneStop) + m_minimum;
                    if (oldValue != m_value)
                    {
                        if (ValueChanged != null)
                        {
                            ValueChanged.Invoke(this, EventArgs.Empty);
                        }
                    }
                }
            }

        }

        private void ClearHighLights()
        {
            bool invalidate = false;
            if (m_onPlus == true || 
                m_onMinus == true || 
                m_onSlider == true)
            {
                invalidate = true;
            }

            m_onMinus = false;
            m_onPlus = false;
            m_onSlider = false;

            m_tooltip.SetToolTip(this, String.Empty);

            if (invalidate == true)
            {
                Invalidate();
            }
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            Calculate();
            base.OnSizeChanged(e);
        }

        private void Calculate()
        {
            int y = (this.ClientRectangle.Height - ms_minus.Height) / 2;
            m_minusRect = new Rectangle(2, y, ms_minus.Width, ms_minus.Height);
            m_plusRect = new Rectangle((this.ClientRectangle.Width - m_plusRect.Width - 2), y, ms_plus.Width, ms_plus.Height);
            m_sliderBorders = new Padding(m_minusRect.Right - 3, 0, m_plusRect.Left - 7 - 2, ms_thumb.Height);

            int oneStop = (m_sliderBorders.Right - m_sliderBorders.Left) / (m_maximum - m_minimum);
            int oldValue = m_value;
            m_value = ((m_sliderRect.X - m_sliderBorders.Left) / oneStop) + m_minimum;
        }


        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            g.DrawImageUnscaled(m_onMinus ? ms_minus_hl : ms_minus, m_minusRect);
            g.DrawImageUnscaled(m_onPlus ? ms_plus_hl : ms_plus, m_plusRect);

            g.DrawImageUnscaled(m_onSlider ? ms_thumb_hl : ms_thumb, m_sliderRect);


            base.OnPaint(e);
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            Rectangle drawRect = this.ClientRectangle;
            if (drawRect.Width == 0 || 
                drawRect.Height == 0)
            {
                return;
            }

            Graphics g = pevent.Graphics;
            g.InterpolationMode = InterpolationMode.NearestNeighbor;

            if (m_transparent == false)
            {
                Color firstColor = Color.FromArgb(197, 220, 248);
                Color secondColor = Color.FromArgb(169, 202, 247);

                Rectangle topDrawRect = new Rectangle(0, 0, drawRect.Width, 7);


                using (Brush brush = new LinearGradientBrush(topDrawRect,
                                    firstColor, secondColor, LinearGradientMode.Vertical))
                {
                    g.FillRectangle(brush, topDrawRect);
                }

                firstColor = Color.FromArgb(144, 182, 234);
                secondColor = Color.FromArgb(116, 149, 194);

                Rectangle bottomDrawRect = new Rectangle(0, topDrawRect.Bottom, drawRect.Width, drawRect.Height - topDrawRect.Height);

                using (Brush brush = new LinearGradientBrush(bottomDrawRect,
                                    firstColor, secondColor, LinearGradientMode.Vertical))
                {
                    g.FillRectangle(brush, bottomDrawRect);
                }
            }
            else
            {
                base.OnPaintBackground(pevent);
            }

            int y = (drawRect.Height - 2) / 2;

            Color borderColor = Color.FromArgb(116, 150, 194);
            Point start = new Point(m_minusRect.Right, y);
            Point end = new Point(drawRect.Width - (m_minusRect.Width + 2), y);
            using (Pen borderPen = new Pen(borderColor))
            {
                g.DrawLine(borderPen, start, end);
            }

            y++;
            borderColor = Color.FromArgb(222, 226, 236);
            start = new Point(m_minusRect.Right, y);
            end = new Point(drawRect.Width - (m_minusRect.Width + 2), y);
            using (Pen borderPen = new Pen(borderColor))
            {
                g.DrawLine(borderPen, start, end);
            }

            y = 6;
            int x = (drawRect.Width - 2) / 2;

            borderColor = Color.FromArgb(116, 150, 194);
            start = new Point(x, y);
            end = new Point(x, y + 7);
            using (Pen borderPen = new Pen(borderColor))
            {
                g.DrawLine(borderPen, start, end);
            }

            y++;
            x++;
            borderColor = Color.FromArgb(222, 226, 236);
            start = new Point(x, y);
            end = new Point(x, y + 7);
            using (Pen borderPen = new Pen(borderColor))
            {
                g.DrawLine(borderPen, start, end);
            }
        }
    }


}
